<?php
namespace mes;

use mes\RSAUtil;
use think\facade\Env;

class Mes {

	protected $privateKey;

	protected $appId;

	protected $appSecure;

	protected $host;

	protected $_debug=false;
    protected $sop_openKeyId;
    protected $sop_secretKey;
    protected $sop_host;

	public function __construct() {
		$this->privateKey = Env::get('mes1.private_key');
		$this->appId = Env::get('mes1.app_id');
		$this->appSecure = Env::get('mes1.app_secure');
		$this->host = Env::get('mes1.host');
		$this->_debug = Env::get('mes1.debug', 0);
        $this->sop_openKeyId = Env::get('mes1.sop_openKeyId');
        $this->sop_secretKey = Env::get('mes1.sop_secretKey');
        $this->sop_host = Env::get('mes1.sop_host');
	}

	public function setConfig($config) {
		$this->privateKey = isset($config['private_key']) ? $config['private_key'] : '';
		$this->appId = isset($config['app_id']) ? $config['app_id'] : '';
		$this->appSecure = isset($config['app_secure']) ? $config['app_secure'] : '';
		$this->host = isset($config['host']) ? $config['host'] : '';
		if(isset($config['debug'])) {
			$this->_debug = $config['debug'];
		}
		return $this;
	}

	/**
	 * 大货 BOM查询
	 *
	 * @author KING
	 * @date 2019年4月10日
	 *
	 * @param string $produceOrderId	订单号
	 */
	public function getBigGoodsBom($produceOrderId) {
		try {
			$uri = "/platform/order/getBigGoodsBom";

			// 头数信息
			$header = $this->_getHeader($uri);

			// 请求URL
			$url = $this->host . $uri;

			// POST参数
			$params = [
				'produceOrderId' => $produceOrderId
			];
			$result = $this->_httpPost($url, $params, 30, $header);

			return $result;

		} catch (\Exception $e) {
			throw new \Exception('请求异常，'.$e->getMessage());
		}
	}

	/**
	 * 订单详情查询
	 *
	 * @author KING
	 * @date 2019年4月10日
	 *
	 * @param string $produceOrderId	订单号
	 */
	public function getProduceOrderInfo($produceOrderId) {
		try {
			$uri = "/platform/order/getProduceOrderInfo";

			// 头数信息
			$header = $this->_getHeader($uri);

			// 请求URL
			$url = $this->host . $uri;

			// POST参数
			$params = [
				'produceOrderId' => $produceOrderId
			];
			$result = $this->_httpPost($url, $params, 30, $header);

			return $result;

		} catch (\Exception $e) {
			throw new \Exception('请求异常，'.$e->getMessage());
		}
	}

	/**
	 * 查询订单采购信息
	 *
	 * @author KING
	 * @date 2019年4月10日
	 *
	 * @param string $produceOrderId	订单号
	 */
	public function purchaseDetailInfoList($produceOrderId) {
		try {
			$uri = "/platform/material/purchaseDetailInfoList";

			// 头数信息
			$header = $this->_getHeader($uri);

			// 请求URL
			$url = $this->host . $uri;

			// POST参数
			$params = [
				'produceOrderId' => $produceOrderId
			];
			$result = $this->_httpPost($url, $params, 30, $header);

			return $result;

		} catch (\Exception $e) {
			throw new \Exception('请求异常，'.$e->getMessage());
		}
	}

	/**
	 * 根据时间区间查询订单
	 *
	 * @author KING
	 * @date 2019年4月10日
	 * @param string $startTime  下单开始时间
	 * @param string $endTime  下单结束时间
	 *
	 */
	public function queryProduceOrderInfo($startTime, $endTime) {
		try {
			$uri = "/platform/order/queryProduceOrderInfo";

			// 头数信息
			$header = $this->_getHeader($uri);

			// 请求URL
			$url = $this->host . $uri;

			// POST参数
			$params = [
				'startTime' => $startTime,
				'endTime' => $endTime,
			];
			$result = $this->_httpPost($url, $params, 600, $header);

			return $result;

		} catch (\Exception $e) {
			throw new \Exception('请求异常，'.$e->getMessage());
		}
	}

	/**
	 * 订单号批量查询订单信息接口
	 *
	 * @author King
	 * @date 2021年1月29日
	 *
	 * @param string $produceOrderIdList		订单编号，最大支持100个
	 * @param number $startTime					接单开始时间
	 * @param number $endTime					接单结束时间
	 * @param string $sku						SKU
	 * @throws \Exception
	 * @return string
	 */
	public function getOrderInfo($produceOrderIdList, $startTime=0, $endTime=0, $sku='') {
		try {
			$uri = "/platform/order/getOrderInfo";

			// 头数信息
			$header = $this->_getHeader($uri);

			// 请求URL
			$url = $this->host . $uri;

			// POST参数
			$params = [
				'produceOrderIdList' => $produceOrderIdList,
			];
			if($startTime) $params['acceptOrderStartTime'] = $startTime;
			if($endTime) $params['acceptOrderEndTime'] = $endTime;
			if($sku) $params['sku'] = $sku;
			$result = $this->_httpPost($url, $params, 600, $header);

			return $result;

		} catch (\Exception $e) {
			throw new \Exception('请求异常，'.$e->getMessage());
		}
	}

	/**
	 * 发货单信息
	 *
	 * @author King
	 * @date 2021年1月29日
	 *
	 * @param string $produceOrderIdList		订单编号，最大支持100个
	 * @param number $startTime					接单开始时间
	 * @param number $endTime					接单结束时间
	 * @param string $sku						SKU
	 * @throws \Exception
	 * @return string
	 */
	public function getDeliverOrderList($produceOrderIdList, $startTime=0, $endTime=0, $sku='') {
		try {
			$uri = "/platform/order/deliverOrder/list";

			// 头数信息
			$header = $this->_getHeader($uri);

			// 请求URL
			$url = $this->host . $uri;

			// POST参数
			$params = [
				'produceOrderIdList' => $produceOrderIdList,
			];
			if($startTime) $params['acceptOrderStartTime'] = $startTime;
			if($endTime) $params['acceptOrderEndTime'] = $endTime;
			if($sku) $params['sku'] = $sku;
			$result = $this->_httpPost($url, $params, 600, $header);

			return $result;

		} catch (\Exception $e) {
			throw new \Exception('请求异常，'.$e->getMessage());
		}
	}

	/**
	 * 获取请求头信息
	 *
	 * @author KING
	 * @date 2019年4月10日
	 *
	 * @param string $uri	请求URI
	 * @return array
	 */
	private function _getHeader($uri) {
		$header = [
			'appId' => $this->appId,
			'appSecure' => $this->appSecure,
			'timestamp' => round(microtime(true)*1000),
			'uri' => $uri,
		];

		// 签名
		$util = new RSAUtil();
		$content = $header['appId'] . ',' . $header['appSecure'] . ',' . $header['uri'] . ',' . $header['timestamp'];
		$header['sign'] = $util->createSign($content, $this->privateKey);

		$header = array_merge(array('Content-Type'=>'application/json'), $header);
		$headers = [];
		foreach ($header as $k => $v) {
			$headers[] = $k . ':' . $v;
		}

		return $headers;
	}

	/**
	 * 发送http请求
	 *
	 * @author KING
	 * @date 2019年4月10日
	 *
	 * @param string $url		请求URL
	 * @param array $data		请求参数
	 * @param integer $timeout	超时时间
	 * @param array $headers	请求头
	 * @return string
	 */
	private function _httpPost($url, $data, $timeout=30, $headers=array()){ // 模拟提交数据函数
		$curl = curl_init(); // 启动一个CURL会话
		curl_setopt($curl, CURLOPT_URL, $url); // 要访问的地址
		curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // 对认证证书来源的检查
		curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是否存在
		curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'POST');
		curl_setopt($curl, CURLOPT_POST, true); // 发送一个常规的Post请求

		curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data, JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE)); // Post提交的数据包
		curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
		curl_setopt($curl, CURLOPT_TIMEOUT, $timeout); // 设置超时限制防止死循环
		curl_setopt($curl, CURLOPT_HEADER, false); // 显示返回的Header区域内容
		curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); // 获取的信息以文件流的形式返回
		curl_setopt($curl, CURLINFO_HEADER_OUT, $this->_debug?true:false); // 启用时,追踪句柄的请求字符串。
		$result = curl_exec($curl); // 执行操作

		if ($this->_debug) {
			$requestHeader = curl_getinfo($curl, CURLINFO_HEADER_OUT);
			//addLog(['header' => $requestHeader, 'body' => json_encode($data, JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE), 'response' => $result], "mes_api_debug");
		}

		if (curl_errno($curl)) {
			throw new \Exception(curl_error($curl));
		}
		curl_close($curl); // 关键CURL会话
		$result = str_replace('":,', '":"",', $result);
		return str_replace(["\r\n", "\r", "\n", "\t"], "", $result); // 返回数据
	}

    /**
     * 根据时间范围查询生产制单号接口
     *返回格式
     * {
     * "code": 0,
     * "info": [
     * 9075927,
     * 9075936
     * ],
     * "msg": "success"
     * }
     * @param $startTime
     * @param $endTime
     * @return string
     * @throws \Exception
     * @author zhuguosen 905502314@qq.com
     * @date 2022/5/31
     */
    public function queryProduceOrderIds($startTime, $endTime)
    {
        try {
            $uri = "/platform/order/queryProduceOrderIds";

            // 头数信息
            $header = $this->_getHeader($uri);

            // 请求URL
            $url = $this->host . $uri;

            // POST参数
            $params = [
                'startTime' => $startTime,
                'endTime' => $endTime,
            ];
            $result = $this->_httpPost($url, $params, 600, $header);

            return $result;

        } catch (\Exception $e) {
            throw new \Exception('请求异常，' . $e->getMessage());
        }
    }

    /**
     * 根据生产制单号查询订单信息接口
     * {
     * "code": 0,
     * "info": {}//订单信息
     * "msg": "success"
     * }
     * @param $produceOrderId
     * @return string
     * @throws \Exception
     * @author zhuguosen 905502314@qq.com
     * @date 2022/5/31
     */
    public function queryProduceOrderInfoById($produceOrderId)
    {
        try {
            $uri = "/platform/order/queryProduceOrderInfoById";

            // 头数信息
            $header = $this->_getHeader($uri);

            // 请求URL
            $url = $this->host . $uri;

            // POST参数
            $params = [
                'produceOrderId' => $produceOrderId
            ];
            $result = $this->_httpPost($url, $params, 600, $header);

            return $result;

        } catch (\Exception $e) {
            throw new \Exception('请求异常，' . $e->getMessage());
        }
    }



    /**
     *  按接单时间查询订单 - (MES新版本接口)
     * @author  huanghuixiang
     * @date 2022/10/21 14:53
     * @param string $startTime  下单开始时间
     * @param string $endTime  下单结束时间
     */
    public function queryProduceOrderInfoV2($startTime,$endTime){
        $requesturl='/sop-api/mes/query-produce-order-info';
        $postdata = [
            'startTime' => $startTime,
            'endTime' => $endTime,
        ];
        $mesInfo_json=$this->postToSopApi($requesturl,$postdata);

        return $mesInfo_json;
    }

    /**
     *  根据订单号查询订单信息 - (MES新版本接口)
     * @author  huanghuixiang
     * @date 2022/10/21 14:53
     * @param string $startTime  下单开始时间
     * @param string $endTime  下单结束时间
     */
    public function queryProduceOrderInfoByIdV2($client_ordernum){
        $requesturl='/sop-api/mes/query-produce-order-info-by-id';
        $postdata = [
            'produceOrderId' => $client_ordernum,
        ];
        $mesInfo_json=$this->postToSopApi($requesturl,$postdata);

        return $mesInfo_json;
    }

    /**
     * 查询mes系统尾货数据
     */
    public function getMesSkuStocks($page=1,$pagesize=20){
        $requesturl='/sop-api/mes/order-inventory-surplus/list';
        //$requesturl="/sop-api/mes/order-inventory-surplus/update";

        $postdata = [
            'pageNo' => $page,'pageSize' => $pagesize,
        ];
        $mesInfo_json=$this->postToSopApi($requesturl,$postdata);
        $mesInfo = json_decode($mesInfo_json, true);

        return $mesInfo;
    }

    /**
     * 获取图片地址
    * @author: sparkguo
    * @Date: 2022-09-15 9:33
    */
    public function getPictruesByOrderNum($orderNumArr,$token){
        $header = $this->_getMesOnlineHeader("wb.4fb88595-5ab9-4167-8418-e9e9d80a6c7c");
        // 请求URL
        $url = "https://www.020mes.com/api/order/focus/new/listOfProduceOrder";
        $orderNumArr=['9920149','9910577'];
        // POST参数
        $postdata = [
            'isLeadTimeDelayed' => 0,'orderStatus'=>-1,'orderStatusCategory'=>1,'pageNo'=>1,'pageSize'=>50,'quickFilterCondition'=>[],'factoryId'=>-1,
            'topSearchCondition' => ['produceOrderIds'=>$orderNumArr,'timeType'=>1]
        ];
        //{"isLeadTimeDelayed":0,"orderStatus":-1,"orderStatusCategory":1,"pageNo":1,"pageSize":30,"quickFilterCondition":{},"topSearchCondition":{"produceOrderIds":["9959454","9959569"],"timeType":1},"factoryId":"-1"}
        $mesInfo_json = $this->_httpPost($url, $postdata, 600, $header);
        $mesRet= json_decode($mesInfo_json, true);
        //{ "code":-101, "msg":"喔哦~系统可能出故障了，请帮忙联系实施人员解救下系统吧！" }
        return $mesRet;
    }

    /**
     * 封装020mes.com线上平台 header请求头
     * @param string $uri	请求URI
     * @return array
     */
    private function _getMesOnlineHeader($token) {
        $header = [
            'Origin'=>'https://www.020mes.com',
            'Referer'=>'https://www.020mes.com/',
            'token' =>$token,
        ];
        $header = array_merge(array('Content-Type'=>'application/json'), $header);
        $headers = [];
        foreach ($header as $k => $v) {
            $headers[] = $k . ':' . $v;
        }
        return $headers;
    }

    /**
     * 更新mes 尾货数
    * @author: sparkguo
    * @Date:  16:49
    */
    public function upMesTailStock($postdata){
        $requesturl='/sop-api/mes/order-inventory-surplus/update';
        //$postdata = [ 'produceOrderId' => 6769153,'sizeInfo' => [['size'=>'M','quantity'=>2],['size'=>'XS','quantity'=>2]] ];
        $mesInfo_json=$this->postToSopApi($requesturl,$postdata);
        $mesInfo = json_decode($mesInfo_json, true);
        return $mesInfo; // [code] => -10000[msg] => 查无订单信息
    }

    /**
     * 新开发平台统一接口调用方法
     * @author: sparkguo
     * @Date:  09-08 11:52
     * @param array $postdata  POST提交参数
     */
    public function postToSopApi($uri,$postdata){
        //try {
            //$uri = "/platform/order/queryProduceOrderInfoById";
            // 头数信息
            $header = $this->_getSopHeader($uri);
            // 请求URL
            $url = $this->sop_host . $uri;
            // POST参数
            $params = [
                // 'produceOrderId' => $produceOrderId
            ];
            $result = $this->_httpPost($url, $postdata, 600, $header);
            return $result;
        //} catch (\Exception $e) {
        //    throw new \Exception('请求异常，' . $e->getMessage());
        //}
    }

    /**
     * 封装sop开发平台请求头信息
     * @param string $uri	请求URI
     * @return array
     */
    private function _getSopHeader($uri) {
        $header = [
            'x-lt-openKeyId' => $this->sop_openKeyId,
            //'x-lt-signature' => $this->appSecure,
            'x-lt-timestamp' => round(microtime(true)*1000),
           // 'uri' => $uri,
        ];
        // 签名
        //1000000&1583398764000&/open-api/order/purchase-order-infos
        $content = $header['x-lt-openKeyId'] . '&' . $header['x-lt-timestamp'] . '&' . $uri;
        $appSecureKey=$this->sop_secretKey;
        $randomKey = $this->_getRandStr(5);
        $securekey = $appSecureKey . $randomKey;
        $header['x-lt-signature'] = $randomKey.$this->createSopSign($content, $securekey);

        $header = array_merge(array('Content-Type'=>'application/json'), $header);
        $headers = [];
        foreach ($header as $k => $v) {
            $headers[] = $k . ':' . $v;
        }
        return $headers;
    }


    /**
     * 创建sop开发平台 hmacSha256加密签名
     * @author: sparkguo
     * @Date:2022-09-09  11:41
     */
    public function createSopSign($content, $priKey){
        //转换成PrivateKey格式
        //$priKey = self::convertPrivateKey($priKey);
        //获取私钥内容
       // $openssl_private_key =  openssl_get_privatekey($priKey);
        //对数据进行PKCS1签名   签名还有MD5,SHA,RMD根据自己实例代码修改
        //openssl_sign($content, $signature, $openssl_private_key, OPENSSL_ALGO_SHA256);
        $signature=hash_hmac( "sha256", $content, $priKey );

        //释放资源
        //openssl_free_key($openssl_private_key);
        //对签名进行Base64编码，变为可读的字符串
        $sign = base64_encode($signature);
        if (empty($sign)) {
            die("验名失败");
        }
        return $sign;
    }


    /**
     * 5位随机码
     * @param $length
     * @return string
     */
    private  function _getRandStr($length){
        //字符组合
        $str = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
        $len = strlen($str)-1;
        $randstr = '';
        for ($i=0;$i<$length;$i++) {
            $num=mt_rand(0,$len);
            $randstr .= $str[$num];
        }
        return $randstr;
    }

    /**
     * 转换PrivateKey
     * @param string $priKey
     * @return string
     */
    private static function convertPrivateKey($priKey) {
        //判断是否传入私钥内容
        $private_key_string = !empty($priKey) ? $priKey : '';
        //64位换行私钥内容
        $private_key_string = chunk_split($private_key_string, 64, "\r\n");
        //私钥头部
        $private_key_header = "-----BEGIN RSA PRIVATE KEY-----\r\n";
        //私钥尾部
        $private_key_footer = "-----END RSA PRIVATE KEY-----";
        //完整私钥拼接
        $private_key_string = $private_key_header.$private_key_string.$private_key_footer;
        return $private_key_string;
    }

}

?>